package com.pioneer.web.book.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pioneer.common.utils.SecurityUtils;
import com.pioneer.web.book.domain.Book;
import com.pioneer.web.book.domain.BorrowRecord;
import com.pioneer.web.book.mapper.BookMapper;
import com.pioneer.web.book.mapper.BorrowRecordMapper;
import com.pioneer.web.book.service.IBookService;
import com.pioneer.web.book.service.IBorrowRecordService;
import com.pioneer.web.book.service.IMailService;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

import static com.pioneer.common.constant.BookConstants.*;

/**
* @author aom-star@outlook.com
* @description 针对表【borrow_record】的数据库操作Service实现
* @createDate 2025-05-18 10:48:32
*/
@Service
public class BorrowRecordServiceImpl extends ServiceImpl<BorrowRecordMapper, BorrowRecord>
    implements IBorrowRecordService {

    @Resource
    private BorrowRecordMapper borrowRecordMapper;

    @Resource
    private IMailService mailService;

    @Resource
    private BookMapper bookMapper;

    @Override
    public void borrowBook(Long bookId) {
        BorrowRecord borrowRecord = new BorrowRecord();
        borrowRecord.setBookId(bookId);
        borrowRecord.setUserId(SecurityUtils.getLoginUser().getUserId());
        borrowRecord.setUserName(SecurityUtils.getLoginUser().getUsername());
        borrowRecord.setBorrowTime(LocalDate.now());
        // 60天借阅期限
        borrowRecord.setReturnTime(LocalDate.now().plusDays(60));
        borrowRecord.setStatus(BOOK_STATUS_NOT_RETURN);
        borrowRecord.setOverdue(BOOK_STATUS_NOT_OVERDUE);
        boolean ret = save(borrowRecord);
        if (!ret) {
            throw new RuntimeException("借书失败喵");
        }
    }

    @Override
    public List<BorrowRecord> selectRecordByUserID(Long userId, String status) {
        return borrowRecordMapper.selectRecordByUserId(userId, status);
    }

    @Override
    public boolean returnBook(List<Long> bookIds) {
        LambdaQueryWrapper<BorrowRecord> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(BorrowRecord::getBookId, bookIds)
                .eq(BorrowRecord::getStatus, BOOK_STATUS_NOT_RETURN);
        List<BorrowRecord> records = borrowRecordMapper.selectList(wrapper);
        if (records.isEmpty()) {
            throw new RuntimeException("没有找到借书记录喵");
        }
        List<BorrowRecord> updateRecords = new ArrayList<>();
        for (BorrowRecord record : records) {
            BorrowRecord updateRecord = new BorrowRecord();
            updateRecord.setId(record.getId());
            updateRecord.setStatus(BOOK_STATUS_RETURN);
            updateRecord.setActualReturnTime(LocalDate.now());
            updateRecords.add(updateRecord);
            // 归还后更新书籍数量
            bookMapper.returnBook(record.getBookId());
        }
        borrowRecordMapper.updateById(updateRecords);
        return true;
    }

    @Override
    public BorrowRecord getBorrowRecordById(Long borrowRecordId) {
        return borrowRecordMapper.selectRecordById(borrowRecordId);
    }

    @Override
    public void cleanOldRecords() {
        LocalDateTime threeMonthsAgo = LocalDateTime.now().minusMonths(3);
        LambdaQueryWrapper<BorrowRecord> wrapper = Wrappers.lambdaQuery();
        wrapper.isNotNull(BorrowRecord::getActualReturnTime)
                .lt(BorrowRecord::getActualReturnTime, threeMonthsAgo);
        remove(wrapper);
    }

    @Override
    public void updateOverdueStatus() {
        LambdaUpdateWrapper<BorrowRecord> wrapper = Wrappers.lambdaUpdate();
        wrapper.eq(BorrowRecord::getStatus, BOOK_STATUS_NOT_RETURN) // 未归还
                .eq(BorrowRecord::getOverdue, BOOK_STATUS_NOT_OVERDUE) // 未更新逾期状态
                .lt(BorrowRecord::getReturnTime, LocalDateTime.now()); // 已过期
        // 发送邮件提醒
        List<BorrowRecord> records = list(wrapper);
        for (BorrowRecord record : records) {
            mailService.sendOverdueNotice(record);
        }
        // 更新逾期状态
        wrapper.set(BorrowRecord::getOverdue, BOOK_STATUS_OVERDUE);
        update(wrapper);
    }
}




